#pragma once

#include <sstream>
#include "TinyJsonValue.h"

namespace tinyjson
{
    enum class TinyJsonParseRet
    {
        TINY_JSON_PARSE_SECCESS,
        TINY_JSON_PARSE_FAIL
    };

    class TinyJsonReader
    {
    private:
        // m_input什么为指针，为了创建1个TinyJsonReader对象，能进行多次解析
        std::shared_ptr<std::istringstream> m_input = nullptr;
        TinyJsonValuePtr m_value = nullptr;
        TinyJsonParseRet m_status = TinyJsonParseRet::TINY_JSON_PARSE_FAIL;

    public:
        TinyJsonReader(){};
        ~TinyJsonReader(){};
        void load_from_string(const char *json);
        void load_from_file(const char *filepath);

        Boolean try_match_char(std::istream &input, char ch);
        Boolean try_match_string(std::istream &input, const String &src);
        Boolean isdigit_1to9(const char ch);
        Boolean parse_hex4(std::istream &input, unsigned int &u);
        void encode_utf8(String &buffer, unsigned u);
        Boolean parse_unicode_string(std::istream &input, String &buffer);
        Boolean parse_key(std::istream &input, String &key);

        const TinyJsonParseRet parse_state() const;
        TinyJsonValue parse_result();
        const TinyJsonValue parse_result() const;

        void parse();
        TinyJsonParseRet parse(std::istream &input, TinyJsonValue &value);
        TinyJsonParseRet parse_tinyjsonvalue(std::istream &input, TinyJsonValue &value);
        TinyJsonParseRet parse_literal(std::istream &input, const char *literal, TinyJsonValue &value);
        TinyJsonParseRet parse_number(std::istream &input, TinyJsonValue &value);
        TinyJsonParseRet parse_string(std::istream &input, TinyJsonValue &value);
        TinyJsonParseRet parse_array(std::istream &input, TinyJsonValue &value);
        TinyJsonParseRet parse_object(std::istream &input, TinyJsonValue &value);
    };
}